import operator
import time
from osv import osv, fields
from osv.orm import intersect
import tools.sql
from tools import config
from tools.translate import _
from mx import DateTime
import netsvc

class purchase_typeoforder(osv.osv):
    _name = 'purchase.typeoforder'
    _description = 'Purchase Type Of Order'
    _columns={
             'code':fields.char('Code',size=1),
             'name':fields.char('Name',size=64)
             }
purchase_typeoforder()
#Purchase
class purchase_order(osv.osv):
    _name = 'purchase.order'
    _inherit = 'purchase.order'
    
    def _delete_all_pol_line(self,cr,uid,ids,context):
        kdvn_pol_ids=[]
        kdvn_pol_obj =self.read(cr,uid,ids,['order_line'])
        if kdvn_pol_obj:
            kdvn_pol_ids =kdvn_pol_obj[0]['order_line'] 
        if kdvn_pol_ids:
            self.pool.get('purchase.order.line').unlink(cr,uid,kdvn_pol_ids,context)        
        return True

    def fields_get(self, cr, uid, fields=None, context=None):
        res = super(purchase_order, self).fields_get(cr, uid, fields, context)
        new_field={'search_in_line_budget':
                                        {'widget':u'char',
                                         'type':u'char',
                                         'name':u'search_in_line_budget',
                                         'select': u'1',
                                         'string':u'Budget',
                                         'invisible':True,
                                         'visible':False,
                                         'size':128,
                                         'sql':"(Select distinct order_id from purchase_order_line pol left join product_product pp on pol.product_id=pp.id left join account_budget_post abp on kdvn_budget_id=abp.id where abp.name || ' ' || abp.code ilike chr(37) || '%s' || chr(37))"}}
        res.update(new_field)
        return res
    
    def create(self, cr, uid, vals, context={}):
        if 'name' in vals:
            order_no = vals['name']
            if order_no:
                cr.execute("Select id from purchase_order po where upper(name)=upper('" + order_no+"')")
                if cr.fetchall():
                    raise osv.except_osv("KDVN Error",'PO Number is exist !')        
        self.pool.get('ir.rule').domain_get.clear_cache(cr.dbname)
        id_test=osv.osv.create(self, cr, uid, vals, context=context)        
        #cr.execute()
        #raise osv.except_osv("E",vals)
        if 'order_payment_term_ids' in vals:
            if vals['order_payment_term_ids']==False:
                kdvn_po_payment_term_line_obj=self.pool.get('kdvn.po.payment.term.line')         
                kdvn_payment_line_id=kdvn_po_payment_term_line_obj.create(cr,uid,{'value_amount':100.0,'name':'100% Payment',
                                                         'sequence':5,'order_id':id_test})
        else:
            kdvn_po_payment_term_line_obj=self.pool.get('kdvn.po.payment.term.line')         
            kdvn_payment_line_id=kdvn_po_payment_term_line_obj.create(cr,uid,{'value_amount':100.0,'name':'100% Payment',
                                                         'sequence':5,'order_id':id_test})
        return id_test
    
    def action_packing_received(self,cr,uid,ids,*args):
        for order in self.browse(cr, uid, ids):
            picking_ids=[]
            for picking_id in order.stock_picking_ids:
                picking_ids.append(picking_id.id)
            if picking_ids:
                self.pool.get('stock.picking').write(cr,uid,picking_ids,{'state':'done'})
            self.write(cr,uid,[order.id],{'state':'delivered'})
        return True

    def inv_line_create(self, cr, uid, a, ol):
        return (0, False, {
            'name': ol.name,
            'account_id': a,
            'price_unit': ol.price_unit or 0.0,
            'quantity': ol.product_qty,
            'product_id': ol.product_id.id or False,
            'uos_id': ol.product_uom.id or False,
            'invoice_line_tax_id': [(6, 0, [x.id for x in ol.taxes_id])],
            'account_analytic_id': ol.account_analytic_id.id,
        })

    def action_picking_create(self,cr, uid, ids, *args):
        picking_id = False
        for order in self.browse(cr, uid, ids):
            if not order.special_case:
                loc_id = order.partner_id.property_stock_supplier.id
                istate = 'none'
                todo_moves = []
                for order_line in order.order_line:
                    if not order_line.product_id:
                        continue
                    if order_line.product_id.product_tmpl_id.type in ('product', 'consu'):
                        if order.location_id:
                            dest = order.location_id.id
                        else:
                            dest = False
                        if order_line.move_dest_id:
                            loc_id = order.location_id.id#self.pool.get('stock.move').write(cr, uid, [order_line.move_dest_id.id], {'location_id':order.location_id.id})
                        todo_moves.append((0,False,{
                            'name': 'PO:'+order_line.name,
                            'product_id': order_line.product_id.id,
                            'product_qty': order_line.product_qty,
                            'product_uos_qty': order_line.product_qty,
                            'product_uom': order_line.product_uom.id,
                            'product_uos': order_line.product_uom.id,
                            'date_planned': order.delivery_date,
                            'location_id': loc_id,
                            'location_dest_id': dest,
                            'picking_id': picking_id,
                            'move_dest_id': order_line.move_dest_id.id,
                            'state': 'draft',
                            'purchase_line_id': order_line.id,
                        }))
                        
                        #todo_moves.append(move)    
#                self.pool.get('stock.move').action_confirm(cr, uid, todo_moves)
#                self.pool.get('stock.move').force_assign(cr, uid, todo_moves)
#                wf_service = netsvc.LocalService("workflow")
#                wf_service.trg_validate(uid, 'stock.picking', picking_id, 'button_confirm', cr)
                picking_id = self.pool.get('stock.picking').create(cr, uid, {
                                    'origin': order.name+((order.origin and (':'+order.origin)) or ''),
                                    'type': 'in',
                                    'address_id': order.partner_address_id.id,
                                    'invoice_state': istate,
                                    'purchase_id': order.id,
                                    'move_lines' : todo_moves,
                                })
                self.write(cr,uid,[order.id],{'state':'roa_completed'})
        return picking_id
    
    def action_check_budget_final_quoatation(self,cr, uid, ids, *args):
        self.write(cr,uid,ids,{'state':'final_quotation'})        
#        mail_obj = self.pool.get('email.smtpclient')
#        smtp_clt_id = mail_obj.search(cr,uid,[('name','=','Kinden Reminder')])
#        if len(smtp_clt_id)>=1:
#            smtp_clt_id = smtp_clt_id[0]
#        
#        bd = ''
#        eml_to = 'duongcdtin5@gmail.com'
#        pol_obj = self.pool.get('purchase.order.line')
#        pol_ids = pol_obj.search(cr,uid,[('order_id','in',ids)])
#        prj = False
#        bd_id =False
#        sent = False
#        reports=[]
#        for pol in pol_obj.browse(cr,uid,pol_ids):
#            if pol.budget_remain_thistime-pol.amountvnd<0:
#                if pol.project_id.id<>prj:
#                    if prj:
#                        #reports.append([prj])
#                        if bd<>"":
#                            n_bd="Dear Sir/Madam,<br><br>As of <b>"+time.strftime('%Y-%m-%d %H:%M:%S')+"</b>, there is an over budget in the code of:"+bd + "<br> Please take a look at the over budget http://openerp.kinden.com.vn:8080/form/view?model=kdvn.project&id="+str(prj)+"<br><br>Best regards,<br><br>---<br>\
#                                    Please DO NOT reply this email that is sent you automatically by KINDEN VIETNAM's OpenERP system. If you think this email is a mistake, please inform IT Section (truong-quang-thanh@kinden.com.vn)"
#                            n_bd2="Dear Sir/Madam,<br><br>Please find the attachments for the most up-to-dated Budget Summary Sheets of your in-charged Jobs as of <b>"+time.strftime('%Y-%m-%d')+"</b><br><br>Best regards,<br><br>---<br>\
#                                    Please DO NOT reply this email that is sent you automatically by KINDEN VIETNAM's OpenERP system. If you think this email is a mistake, please inform IT Section (truong-quang-thanh@kinden.com.vn)"
#                        a=mail_obj.send_email(cr,uid,smtp_clt_id,eml_to,' Over budget alert',n_bd,[],[])
#                        a=mail_obj.send_email(cr,uid,smtp_clt_id,eml_to,' Over budget alert',n_bd2,[],[reports])
#                        sent = True
#                    bd=""
#                    #eml_to = pol.project_id.project_manager_id.email_address
#                    prj = pol.project_id.id
#                if pol.product_id.kdvn_budget_id.id<>bd_id:
#                    sent = False
#                    reports=['report.budget.balance.sheet.rev01',[pol.project_id.id],{'model':'kdvn.project'},'BudgetBalanceSheet-'+pol.project_id.code]                    
#                    bd = bd+ "<b>" + pol.product_id.kdvn_budget_id.code + "</b> of the job <b>" + pol.project_id.code +"</b>."
#                    bd_id=pol.product_id.kdvn_budget_id.id
#        if not sent and bd<>"":
#            n_bd="Dear Sir/Madam,<br><br>As of <b>"+time.strftime('%Y-%m-%d %H:%M:%S')+"</b>, there is an over budget in the code of:"+bd + "<br> Please take a look at the over budget http://openerp.kinden.com.vn:8080/form/view?model=kdvn.project&id="+str(prj)+"<br><br>Best regards,<br><br>---<br>\
#                                    Please DO NOT reply this email that is sent you automatically by KINDEN VIETNAM's OpenERP system. If you think this email is a mistake, please inform IT Section (truong-quang-thanh@kinden.com.vn)"
#            n_bd2="Dear Sir/Madam,<br><br>Please find the attachments for the most up-to-dated Budget Summary Sheets of your in-charged Jobs as of <b>"+time.strftime('%Y-%m-%d')+"</b><br><br>Best regards,<br><br>---<br>\
#                                    Please DO NOT reply this email that is sent you automatically by KINDEN VIETNAM's OpenERP system. If you think this email is a mistake, please inform IT Section (truong-quang-thanh@kinden.com.vn)"
#            a=mail_obj.send_email(cr,uid,smtp_clt_id,eml_to,'Over budget alert',n_bd,[],[])
#            a=mail_obj.send_email(cr,uid,smtp_clt_id,eml_to,'Over budget alert',n_bd2,[],[reports])
        return True
               
    def action_cancel(self, cr, uid, ids, context={}):
        ok = True
        purchase_order_line_obj = self.pool.get('purchase.order.line')
        for purchase in self.browse(cr, uid, ids):
            inv = purchase.rop_ids
            if inv:# and inv.state not in ('cancel','draft'):
                raise osv.except_osv(
                    _('Could not cancel this purchase order !'),
                    _('You must first cancel all Request Of Payment attached to this purchase order.'))
        self.write(cr,uid,ids,{'state':'cancel'})
        return True
    
    def action_cancel_draft(self, cr, uid, ids, *args):
        if not len(ids):
            return False
        self.write(cr, uid, ids, {'state':'draft'})
        wf_service = netsvc.LocalService("workflow")
        for p_id in ids:
            wf_service.trg_create(uid, 'purchase.order', p_id, cr)
        return True    
    #New Code
    
    def _get_order(self, cr, uid, ids, context={}):
        result = {}
        for line in self.pool.get('purchase.order.line').browse(cr, uid, ids, context=context):
            result[line.order_id.id] = True
        return result.keys()
    
    def  _cal_untaxed(self, cr, uid, ids, field_name, arg, context):
        res = {}
        #cur_obj=self.pool.get('res.currency')
        if ids:
            order_ids ='('+ ','.join(map(str,ids))+')'
            cr.execute("Select \
                            po.id,\
                            sum(price_unit*case when state<>'done' and po.special_case=True then plan_qty else product_qty end) as price_subtotal\
                        from \
                            purchase_order po\
                        left join\
                            purchase_order_line pol on po.id = pol.order_id\
                        where po.id in (%s)\
                        group by po.id" % order_ids)
            for order_id,amount in cr.fetchall():
                res[order_id] = amount
        return res
    
    def _new_code(self,cr,uid,ids,job_id,order_type,name=False):
        if order_type:
            po_type_obj=self.pool.get('purchase.typeoforder').browse(cr,uid,order_type)
            order_type = po_type_obj.code
#        raise osv.except_osv("Warning",order_type)
        if ids:
            ids=ids[0]
        else:
            ids=0
        if not (order_type and job_id):
            val={'value':{'name':'Not Available'}}
        else:
            job_code_list=self.pool.get("kdvn.project").read(cr,uid,job_id,['code'])
            if not job_code_list:
                val={'value':{'name':'Not Available'}}
            else:
                job_code = job_code_list['code']
                project_code_len = 0
                project_code_len = len(str(job_code)+"-M")+1
                
                cr.execute("Select \
                                max(substring(name from "+str(project_code_len)+" for length(name)-"+str(project_code_len-1)+"))::integer \
                            from \
                                purchase_order \
                            where name like '"+job_code+"-"+order_type.upper()+"%' and id!="+str(ids))
                if cr.rowcount:
                    next_code=str(cr.fetchone()[0])
                    #raise osv.except_osv("E",next_code)
                    if next_code.isdigit():
                        next_code=str(int(next_code)+1)
                    else:
                        next_code='1'
                else:
                    next_code='1'
                val={'value':{'name':job_code+'-'+order_type.upper()+next_code.rjust(3,'0')}}
            return val
    
    def _onchange_dateorder(self,cr,uid,ids,date_order,currency_id):
#        cur_obj=self.pool.get("kdvn.purchase.currency")
        #raise osv.except_osv("E","%s-%s" %(date_order,currency_id))
        
        if not date_order or not currency_id:
            return {'value':{'ref_exrate':0.0,'exrate':0.0}}
        else:
            cr.execute("Select coalesce(case when fnpo_curridtoname(%s)='VND'\
                                    then \
                                        fnpo_compute(fnpo_currnametoid('VND'),fnpo_currnametoid('USD'),'%s'::date) \
                                        else fnpo_compute(fnpo_currnametoid('VND'),%s,'%s'::date) end,0)" % (currency_id,date_order,currency_id,date_order))
            rate_obj = cr.fetchone()
            if not rate_obj:
                val = {'value':{'ref_exrate':0.0,'exrate':0.0}}
            else:
                val={'value':{'ref_exrate':rate_obj[0],'exrate':rate_obj[0]}}
                return val
    
    def _exrate(self, cr, uid, ids, name, arg, context={}):
        res = {}
        if ids:
            cr.execute("Select id,\
                                case when fnpo_curridtoname(currency_id)='VND'\
                                then \
                                    fnpo_compute(fnpo_currnametoid('VND'),fnpo_currnametoid('USD'),date_order) \
                                    else fnpo_compute(fnpo_currnametoid('VND'),currency_id,date_order) end\
                        from purchase_order where id in (%s) " % ",".join(map(str, ids)))
        for po_id, rate in cr.fetchall():
            res[po_id] = rate
        for obj_id in ids:
            res.setdefault(obj_id, 0.0)
        for id in ids:
            res[id] = res.get(id, 0.0)
        return res

    def action_cancel_draft(self, cr, uid, ids, *args):
        if not len(ids):
            return False
        self.write(cr, uid, ids, {'state':'draft'})
        wf_service = netsvc.LocalService("workflow")
        for p_id in ids:
            wf_service.trg_create(uid, 'purchase.order', p_id, cr)
        return True
    
    def button_dummy(self, cr, uid, ids, context={}):
        cur_obj=self.read(cr,uid,ids,['line_update'],context=context)
        checking=cur_obj[0]['line_update']
        if checking:
            cr.execute("Update purchase_order set line_update=False,discount=(Select sum(price_unit*product_qty)-sum(price_subtotal2) as discount from purchase_order_line where order_id=%d),\
                        discount_percent=(Select (sum(price_unit*product_qty)-sum(price_subtotal2))/sum(price_unit*product_qty)*100.0 as discount_percent from purchase_order_line where order_id=%d) where id=%d;" % (ids[0],ids[0],ids[0]))
            cr.execute("update purchase_order_line set price_subtotal2=price_unit*product_qty-price_unit*product_qty*discount_percent/100.0 where price_subtotal2  is null")
            #,\
             #           amount_total2=(Select sum(price_subtotal2) as amount_total2 from purchase_order_line where order_id=%d)  ,ids[0]
            val=False
        else:
            cur_obj=self.read(cr,uid,ids,['amount_untaxed','discount'])
            amount=cur_obj[0]['amount_untaxed'] or 0.0
            discount=cur_obj[0]['discount'] or 0.0
            osv.osv.write(self, cr, uid, ids, {'amount_total2':amount-discount})
            val=amount-discount
        return val

    def write(self, cr, uid, ids, vals, context=None):
        if 'name' in vals:
            order_no = vals['name']
            po_id = ids[0]
            if order_no:
                cr.execute("Select name from purchase_order po where id=%d" % (po_id))
                res2=cr.fetchone()
                new_name = res2[0]
                if new_name.upper().strip()!=order_no.upper().strip():
                    cr.execute("Select name from purchase_order po where id<>%d and name ilike '%s'" % (po_id,order_no))
                    if cr.fetchall():
                        raise osv.except_osv("KDVN Error",'PO Number is exist !')
        cur_obj=self.read(cr,uid,ids,['line_update'],context=context)
        checking=cur_obj[0]['line_update']
        if checking:
            vals['line_update']  =False
            cr.execute("Select \
                                sum(price_unit*case when state<>'done' and po.special_case=True then plan_qty else product_qty end)-sum(price_subtotal2) as discount,\
                                case when sum(price_unit*case when state<>'done' and po.special_case=True then plan_qty else product_qty end)=0\
                                then 0 else (sum(price_unit*case when state<>'done' and po.special_case=True then plan_qty else product_qty end)-\
                                sum(price_subtotal2))/sum(price_unit*case when state<>'done' and po.special_case=True then plan_qty else product_qty end)*100.0 \
                                end as discount_percent\
                            from \
                                purchase_order_line pol\
                            left join\
                                purchase_order po on pol.order_id = po.id\
                             where order_id=%d" % ids[0])
            values = cr.fetchone()
            if 'tax_amount' in vals:
                dummy = vals.pop('tax_amount')
            if values:
                vals['discount'] = values[0]
                vals['discount_percent'] = values[1]
        else:
            cur_obj=self.read(cr,uid,ids,['amount_untaxed','discount'])
            amount=cur_obj[0]['amount_untaxed'] or 0.0
            discount=cur_obj[0]['discount'] or 0.0
            vals['amount_total2']=amount-discount
        self.pool.get('ir.rule').domain_get.clear_cache(cr.dbname)
        osv.osv.write(self, cr, uid, ids,vals,context=context)          
        return True
    
    def _calc_tax_amount(self, cr, uid, ids, name, arg, context={}):
        res = {}
        if ids:
            order_ids=','.join(map(str,ids))
            cr.execute('Select \
                            po.id,\
                            sum(price_subtotal2)*(coalesce(tax_per,0)/100.0) as tax_amount\
                        from \
                            purchase_order_line pol\
                        right join\
                            purchase_order po on pol.order_id = po.id\
                        where po.id in (%s)\
                        group by po.id,tax_per' % order_ids)
            for o_id,amount in cr.fetchall():
                res[o_id] = amount
        for id in ids:
            res[id] = res.get(id, 0.0)
        return res
    
    def _calc_total(self, cr, uid, ids, name, arg, context={}):
        res = {}
        for po in self.browse(cr,uid,ids):
            res[po.id]=po.amount_total2+po.tax_amount
        for id in ids:
            res[id] = res.get(id, 0.0)
        return res
    
    def _red_invoice_lists(self, cr, uid, ids, name, arg, context=None):
        res = {}
        for id in ids:
            cr.execute("Select \
                                kdvn_purchase_red_invoice_id\
                        from \
                            kdvn_request_of_payment krop \
                        left join \
                            kdvn_request_of_payment_kdvn_purchase_red_invoice_rel kroprir on id=rop_id \
                        where \
                            kdvn_purchase_red_invoice_id>0 and state not in ('draft','cancel') and order_id=(%s)" % id)
            res[id] = [x[0] for x in cr.fetchall()]
            #raise osv.except_osv("Error",res)
        return res
    
    def _get_payment_vatinvoice_info(self, cr, uid, ids, name, args, context=None):
        #tmp={'quotations':False, 'scopeofwork':False}
        res={}
        if ids:
#            tmp_list = {'vat_invoices_amount':0.0,'total_payment':0.0}
            order_ids = ','.join(map(str,ids))
            cr.execute("Select  \
                            po.id,\
                            sum(coalesce(kp.amount,0)) as total_payment,\
                            coalesce(total_vat_amount,0) as vat_invoices_amount\
                        from\
                            purchase_order po\
                        left join\
                            (Select\
                                order_id,sum(total_amount) as total_vat_amount\
                            from \
                                kdvn_request_of_payment krop\
                            left join \
                                kdvn_request_of_payment_kdvn_purchase_red_invoice_rel kroprir on id=rop_id\
                            left join\
                                kdvn_purchase_red_invoice ri on kdvn_purchase_red_invoice_id=ri.id\
                            where ri.id>0 and state not in ('draft','cancel') and order_id in (%s)\
                            group by order_id) vwtotal_vat_inovices on po.id = order_id\
                        left join\
                            kdvn_request_of_payment krop on po.id = krop.order_id and krop.state not in ('draft','cancel')\
                        left join\
                            kdvn_payment kp on krop.id = kp.payment_id\
                        where\
                            po.id in (%s)\
                        group by\
                            po.id,total_vat_amount;" % (order_ids,order_ids))
            for po_vat_payment_total in cr.dictfetchall():
                res[po_vat_payment_total.pop('id')]=po_vat_payment_total
                
        return res
     
    def _amount_after_discount(self, cr, uid, ids, name, arg, context={}):
        #(self, cr, uid, ids, name, arg, context={}):
        res={}
        if ids:
            po_ids = ",".join(map(str,ids))
            cr.execute("Select id,coalesce(amount_untaxed,0)-coalesce(discount,0) as total from purchase_order where id in (%s)" % po_ids)
        for id,total in cr.fetchall():
            res[id] = total
        return res
    
    def _new_type_def(self, cr, uid, context):
        typeoforder = False
        if context:
            if 'typeoforder' in context:
                typeoforder = context['typeoforder']
        return typeoforder

    def _new_project_id(self, cr, uid, context):
        prj_id = False
        if context:
            if 'prj_context_id' in context:
                prj_id = context['prj_context_id']
        return prj_id
    
    def _get_default_without_contract(self, cr, uid, context):
        without_contract = False
        if context:
            if 'without_contract' in context:
                without_contract = context['without_contract']
        return without_contract
    
    def _get_payment_term(self, cr, uid, ids, name, args, context=None):
        res={}
        if ids:
            for id in ids:
                res[id] = False
            order_ids = ','.join(map(str,ids))
            cr.execute("Select \
                            po.id,\
                            pt.name as name \
                        from \
                            purchase_order po \
                        left join\
                            kdvn_po_payment_term_line pt on po.id=order_id where po.id in (%s) and pt.id>0 order by pt.sequence" % (order_ids))
            count = 0
            tmp_obj = cr.fetchall()
            if len(tmp_obj)<=1:
                for po_id,term_name in tmp_obj:
                    res[po_id] = term_name
            else:
                for po_id,term_name in tmp_obj:
                    count+=1
                    if res[po_id]:
                        res[po_id] = res[po_id] + "\n" + str(count) + ". " + term_name
                    else:
                        res[po_id] = str(count) + ". " + term_name
        return res
    
    _columns={
        'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse',states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'location_id': fields.many2one('stock.location', 'Destination',states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
              
        'special_case':fields.boolean('Multi Delivery',readonly=True,states={'draft':[('readonly',False)]}),
        'without_contract':fields.boolean("Without Contract",states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        
        'combine_term':fields.function(_get_payment_term,method=True,type='text',string='Combine Term Name',states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'name': fields.char('Order Reference', size=64, required=True, select=True,states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'date_order':fields.datetime('Date', required=True, states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}, help="Date on which this document has been created."),
        'partner_id':fields.many2one('res.partner', 'Supplier', required=True, states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}, change_default=True),
        'partner_address_id':fields.many2one('res.partner.address', 'Address', required=True, states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'user_id': fields.many2one('res.users', 'User request',states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        #'typeoforder': fields.selection([('m','Material'),('e','Equipment')],'Type of order',states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'user_purchase':fields.many2one('res.users', 'Send to',states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'effective_date': fields.date('Effective Date',states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'to_date': fields.date('To',states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'advance_payment': fields.float('Adv. Payment',states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'progress': fields.float('Progress',states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'retention':fields.float('Retention',states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'discount_percent':fields.float('Disc.(%)',states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'discount':fields.float('Discount',states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'order_line': fields.one2many('purchase.order.line', 'order_id', 'Order Lines', states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'line_update': fields.boolean('Line Update',help='For checking priority line update or main update'),
        'project_id':fields.many2one('kdvn.project','Project',required=True,states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'order_payment_term_ids':fields.one2many('kdvn.po.payment.term.line','order_id','Payment Term',states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'incoterm_id':fields.many2one('incoterm','Incoterm',states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'country_of_origin':fields.many2one('res.country','Country',states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'state': fields.selection([('draft', 'Negotiating'),
                                   ('final_quotation', 'Waiting for Request of Approval'),
                                   ('roa_completed', 'Waiting for Delivery'),
                                   ('delivered','Waiting for Payment'),
                                   ('done', 'PO Completed'),
                                   ('cancel', 'PO Canceled')], 'Order Status', readonly='True'),
        'exp_status':fields.selection([('draft','Draft'),('waiting','Waiting for payment'),('done','Done')],'Status',readonly='True'),
        'typeoforder': fields.many2one('purchase.typeoforder','Type of order',states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        #'typeoforder': fields.selection([('m','Material'),('s','Sub-Contractor'),('e','Site Expense')],'Type of order',states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'ref_exrate':fields.float('Ref. Ex.Rate',states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'amount_untaxed': fields.float('Untaxed Amount',digits=(16,2),readonly=True),#function(_cal_untaxed, method=True, string='Untaxed Amount',type='float',
                                  #        store={'purchase.order.line': (_get_order, None, 10)}),
        'tax_per':fields.float("VAT (%)",states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),#"VAT (%)",states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}
        'tax_amount':fields.float('Tax Amount',digits=(16,2)),#function(_calc_tax_amount,method=True,string="Tax Amount",type='float',states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        
        'currency_id':fields.many2one('kdvn.purchase.currency','Cur.',required=True,states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'exrate':fields.function(_exrate,method=True,string="Ex.Rate",type='float'),
        'rop_ids':fields.one2many('kdvn.request.of.payment','order_id','Payment to Supplier',states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        
        'discount_percent':fields.float(string='Disc.(%)',states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'discount':fields.float(string='Discount',states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'amount_total2':fields.float('After Discount',digits=(16,2),readonly=True),#function(_amount_after_discount,string='After Discount',
                                        #type="float",method=True,states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'total_amount':fields.float('Total',readonly=True,digits=(16,2)),#function(_calc_total,method=True,string="Total",type='float'),
        'notes': fields.text('Notes',states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'origin': fields.char('Order Ref.', size=64,states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        #This section field for Contract to supplier date (cts)
        'cts_date_of_contract':fields.date('Date of contract to supplier',states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'cts_date_of_submitting':fields.date('Date of Submitting',states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'cts_date_of_scanned':fields.date('Date of Scanned',states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'cts_date_of_sending':fields.date('Date of Sending',states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'cts_date_of_receiving':fields.date('Date of Receiving',states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'delivery_date':fields.date('Date of Delivery',states={'done':[('readonly',True)], 'cancel':[('readonly',True)]}),
        'red_invoice_ids':fields.function(_red_invoice_lists,method=True,type="one2many",relation='kdvn.purchase.red.invoice',string='Red Invoice Lists'),
        'vat_invoices_amount':fields.function(_get_payment_vatinvoice_info,string='VAT Invoices Total',method=True,type='float',digits=(16,2),multi='get_payment_info'),
        'total_payment':fields.function(_get_payment_vatinvoice_info,string='VAT Invoices Total',method=True,type='float',digits=(16,2),multi='get_payment_info'),
        
        'stock_picking_ids':fields.one2many('stock.picking','purchase_id','Delivery',readonly=True)
        }
    _order = "name"    
    _defaults={
              'exp_status':lambda *a:'draft',
              'tax_per':lambda *x:10,
              'tax_amount':lambda *x:0.0,
              'amount_total2':lambda *x:0.0,
              'discount_percent':lambda *x:0.0,
              'discount':lambda *x:0.0,
              'ref_exrate':lambda *x:1.0,
              'user_id':lambda obj,cr,uid,context: uid,
              'typeoforder':_new_type_def,
              'special_case':lambda *a:False,
              'project_id':_new_project_id,
              'without_contract':_get_default_without_contract,
              }
    
    def onchange_warehouse_id(self, cr, uid, ids, warehouse_id):
        if not warehouse_id:
            return {}
        res = self.pool.get('stock.warehouse').read(cr, uid, [warehouse_id], ['lot_input_id'])[0]['lot_input_id'][0]
        return {'value':{'location_id': res}}
    
    def _discountp_change(self,cr,uid,ids,a_untaxed,discountp,discount,check={}):
        change=False
        res={}
        per=False
        if not check['per']:
            per = False
            discountp=0.0
        else:
            per=True
            discount=0.0
        if per and ids:
            vdistcount=a_untaxed*discountp/100
            vamountdiscount=a_untaxed-vdistcount
        #raise osv.except_osv(_('Invalid action !'), _('Cannot delete Purchase Order(s) which are in %s State!' % ids))
   
            cr.execute("Update purchase_order_line set \
                            discount_percent=" + str(discountp)+",\
                            price_subtotal2=price_unit*\
                            (case when (Select id from purchase_order where state<>'done' and special_case=True and id=" + str(ids[0]) + ")>0 then plan_qty else product_qty end)\
                            -price_unit*(case when (Select id from purchase_order where state<>'done' and special_case=True and id=" + str(ids[0]) + ")>0 then plan_qty else product_qty end)/100.0*" +str(discountp)+" where order_id="+str(ids[0]))
            #cr.execute("Update purchase_order set line_update=False where id=%d;" % (ids[0]))
            #raise osv.except_osv(_('Invalid action !'), _('Cannot delete Purchase Order(s) which are in %s State!' % ol))
            res={'value':{'discount':vdistcount,'amount_total2':vamountdiscount}}
        elif ids:
            if a_untaxed>0:
                per_amount = discount/a_untaxed*100
            else:
                per_amount=0
            discountp = per_amount
            cr.execute("Update purchase_order_line set \
                            discount_percent=" + str(discountp)+",\
                            price_subtotal2=price_unit*\
                            (case when (Select id from purchase_order where state<>'done' and special_case=True and id=" + str(ids[0]) + ")>0 then plan_qty else product_qty end)-price_unit*(case when (Select id from purchase_order where state<>'done' and special_case=True and id=" + str(ids[0]) + ")>0 then plan_qty else product_qty end)/100.0*" +str(discountp)+" where order_id="+str(ids[0]))
            #cr.execute("Update purchase_order set line_update=False where id=%d;" % (ids[0]))
            #raise osv.except_osv(_('Invalid action !'), _('Cannot delete Purchase Order(s) which are in %s State!' % ol))
            vamountdiscount=a_untaxed-discount
            res={'value':{'discount_percent':per_amount,'amount_total2':vamountdiscount}}
        return res

    def onchange_partner_id(self, cr, uid, ids, part):
        if not part:
            return {'value':{'partner_address_id': False}}
        addr = self.pool.get('res.partner').address_get(cr, uid, [part], ['default'])
        part = self.pool.get('res.partner').browse(cr, uid, part)    
        return {'value':{'partner_address_id': addr['default']}}

    def on_tax_percent_change(self, cr, uid, id, tax_per,amount,tax_amount=False):
        order_amount=amount or 0.0
        tax_per=tax_per or 0
        if tax_amount:
            total_amount=tax_amount+order_amount
        else:
            tax_amount=tax_per*order_amount/100.0        
            total_amount=tax_amount+order_amount
        #raise osv.except_osv("Error",order_amount)
        return {'value':{'tax_amount':tax_amount,'total_amount':total_amount}} 
    
    def action_kdvn_po_cancel(self,cr,uid,ids,*args):
        self.write(cr,uid,ids,{'state':'cancel'})
        return True
    
    def action_kdvn_po_q_sent(self,cr,uid,ids,*args):
        if not len(ids):
            return False
        wf_service = netsvc.LocalService("workflow")
        for pr_id in ids:
            wf_service.trg_validate(uid, 'purchase.order', pr_id,'user_confirm', cr)
        return True
    
    def action_kdvn_mur_q_material(self,cr,uid,ids,*args):
        if not len(ids):
            return False
        wf_service = netsvc.LocalService("workflow")
        for pr_id in ids:
            wf_service.trg_validate(uid, 'purchase.order', pr_id,'pr_confirm', cr)
        return True
    
    def action_kdvn_pc_confirmed(self,cr,uid,ids,*args):
        if not len(ids):
            return False
        wf_service = netsvc.LocalService("workflow")
        for pr_id in ids:
            wf_service.trg_validate(uid, 'purchase.order', pr_id,'manager_purchase_confirm', cr)
        return True
    
    def action_kdvn_confirmed(self, cr, uid, ids, context={}):
        if not len(ids):
            return False
        wf_service = netsvc.LocalService("workflow")
        for pr_id in ids:
            wf_service.trg_validate(uid, 'purchase.order', pr_id,'purchase_confirm', cr)
        return True

    def payment_detail_create(self,project_id,budget_id,budgetname,amount,po_term_type,adv,retention,progress):
#        if ol.product_qty<>0:
#            p_unit=ol.price_subtotal2/ol.product_qty
#        else:
#            p_unit=0.0
#        if ol.project_id:
#            project_id =ol.project_id.id
#        else:
#            project_id = prj_id
        retention_amount = 0.0
        progress_amount=0.0
        adv_amount = 0.0
        if po_term_type<>'p':
            progress_amount =0.0
            if po_term_type=='adv':
                adv_amount = adv * amount/100.0
                retention_amount = 0.0
                progress_amount=0.0
            else:
                adv_amount = 0.0
                progress_amount=0.0
                retention_amount = amount*retention/100.0
        else:
            progress_amount = amount*progress/100.0
            adv_amount = - adv * amount*progress/100.0/100.0
            retention_amount = - retention * amount*progress/100.0/100.0
        return (0, False, {
            'project_id':project_id,
            #'product_id': a,
            #'quantity':ol.product_qty or 0.0,
            'budget_id':budget_id,
            'description':budgetname,
            #'unit':ol['product_uom'][0] or False,
            #'price_unit':p_unit,
            'amount': progress_amount,
            'advanced_amount':adv_amount,
            'retention_amount':retention_amount
        })
        
    def action_expense_create_payment(self, cr, uid, ids, *args):
        res = False
        #for o in self.browse(cr, uid, ids):
        for o in self.read(cr, uid, ids,['order_payment_term_ids',
                                         'amount_total2',
                                         'order_line',
                                         'tax_per',
                                         'tax_amount',
                                         'partner_id',
                                         'currency_id',
                                         'project_id',
                                         'id','rop_ids','notes'
                                         ]):        
            if o['rop_ids']:
                self.write(cr, uid, ids, {'state':'delivered','exp_status':'waiting'})
                wf_service = netsvc.LocalService("workflow")
                try:
                    wf_service.trg_delete(uid, self._name, o['id'], cr)
                except:
                    a = True
                return True
                #raise osv.except_osv('Warning','Request of payment already exist')
            payment_details = []
            adv_amount = 0.0
            retention_amount = 0.0
            adv = 0.0
            retention = 0.0
            progress = 0.0
            for po_term in self.pool.get('kdvn.po.payment.term.line').read(cr,uid,o['order_payment_term_ids'],['type','value_amount']):
                if po_term['type']=='adv':
                    adv_amount = po_term['value_amount']*o['amount_total2']/100
                    adv = po_term['value_amount']
                elif po_term['type']=='re':
                    retention_amount = po_term['value_amount']*o['amount_total2']/100
                    retention = po_term['value_amount']
                else:                    
                    progress = po_term['value_amount']
            for po_term in self.pool.get('kdvn.po.payment.term.line').read(cr,uid,o['order_payment_term_ids'],['type','value_amount','name']):
                if po_term['type']<>'p':
                    this_tax_amount = 0.0
                    this_progress_amount = 0.0
                    if po_term['type']=='adv':
                        this_retention_amount = 0.0
                        this_adv_amount = adv_amount
                    else:
                        this_adv_amount = 0.0
                        this_retention_amount = retention_amount
                else:
                    #progress = po_term['value_amount']
                    this_tax_amount = o['tax_amount']*po_term['value_amount']/100.0
                    this_progress_amount = o['amount_total2']*po_term['value_amount']/100.0
                    this_adv_amount = - adv_amount*progress/100.0
                    this_retention_amount = - retention_amount*progress/100.0
                payment_details = []
                cr.execute("Select\
                                pol.project_id,\
                                kdvn_budget_id,\
                                abp.name as budget_name,\
                                sum(price_subtotal2)\
                            from \
                                purchase_order_line pol\
                            left join\
                                product_product pp on product_id = pp.id\
                            left join\
                                account_budget_post abp on kdvn_budget_id = abp.id\
                            where order_id=%s\
                            group by\
                                pol.project_id,\
                                kdvn_budget_id,\
                                budget_name" % (o['id']))
                for project_id,budget_id,budgetname,amount in cr.fetchall():
                #self.pool.get('purchase.order.line').read(cr,uid,o['order_line'],['product_id','project_id','product_uom','price_subtotal2','name']):
                    #pr_id = budget_id
                    #prj_id = o.project_id.id
                    #raise osv.except_osv("E","%s-%s-%s" %(adv,retention,progress))
                    payment_details.append(self.payment_detail_create(project_id,budget_id,budgetname,amount,po_term['type'],adv,retention,progress))

                if o['notes']:
                    new_description = o['notes']
                else:
                    new_description = ""
                                 
                payment = {
                    'paymentno':'',
                    'amount':this_progress_amount,
                    'tax_amount':this_tax_amount,
                    'advanced_amount':this_adv_amount,
                    'retention_amount':this_retention_amount,
                    'tax_per':int(o['tax_per']) or 0,
                    'supplier_id': o['partner_id'][0],
                    'currency_id': o['currency_id'][0],
                    'detail_ids': payment_details,
                    'order_id':o['id'], # For KDVN,
                    'project_id':o['project_id'][0],
                    'description':new_description#po_term['name'] + "\n"+  o['notes']
                    }
                #raise osv.except_osv("E",payment)
                kdvn_rop_id = self.pool.get('kdvn.request.of.payment').create(cr, uid, payment)
                self.write(cr, uid, ids, {'state':'delivered','exp_status':'waiting'})
                wf_service = netsvc.LocalService("workflow")
                try:
                    wf_service.trg_delete(uid, self._name, o['id'], cr)
                except:
                    a = True
                #    wf_service.trg_create(uid, 'purchase.order', p_id, cr)
        return kdvn_rop_id
    
    def action_cancel_draft_other_expense(self, cr, uid, ids, *args):        
        self.write(cr, uid, ids, {'exp_status':'draft','state':'draft'})
        return True
    
    def action_invoice_create(self, cr, uid, ids, *args):
        res = False
        kdvn_rop_id = False
        #for o in self.browse(cr, uid, ids):
        for o in self.read(cr, uid, ids,['order_payment_term_ids',
                                         'amount_total2',
                                         'order_line',
                                         'tax_per',
                                         'tax_amount',
                                         'partner_id',
                                         'currency_id',
                                         'project_id',
                                         'id','rop_ids','notes'
                                         ]):        
            if o['rop_ids']:
                raise osv.except_osv('Warning','Request of payment already exist')
            payment_details = []
            adv_amount = 0.0
            retention_amount = 0.0
            adv = 0.0
            retention = 0.0
            progress = 0.0
            check_payment_term = False
            for po_term in self.pool.get('kdvn.po.payment.term.line').read(cr,uid,o['order_payment_term_ids'],['type','value_amount']):
                check_payment_term = True
                if po_term['type']=='adv':
                    adv_amount = po_term['value_amount']*o['amount_total2']/100
                    adv = po_term['value_amount']
                elif po_term['type']=='re':
                    retention_amount = po_term['value_amount']*o['amount_total2']/100
                    retention = po_term['value_amount']
                else:                    
                    progress = po_term['value_amount']
                    
            if not check_payment_term:
                raise osv.except_osv("KDVN Error",'You must input payment term for this order before create payment')
            for po_term in self.pool.get('kdvn.po.payment.term.line').read(cr,uid,o['order_payment_term_ids'],['type','value_amount','name','due_date']):
                if po_term['type']<>'p':
                    this_tax_amount = 0.0
                    this_progress_amount = 0.0
                    if po_term['type']=='adv':
                        this_retention_amount = 0.0
                        this_adv_amount = adv_amount
                    else:
                        this_adv_amount = 0.0
                        this_retention_amount = retention_amount
                else:
                    progress = po_term['value_amount']
                    this_tax_amount = o['tax_amount']*po_term['value_amount']/100.0
                    this_progress_amount = o['amount_total2']*po_term['value_amount']/100.0
                    this_adv_amount = - adv_amount*progress/100.0
                    this_retention_amount = - retention_amount*progress/100.0
                payment_details = []
                cr.execute("Select\
                                pol.project_id,\
                                kdvn_budget_id,\
                                abp.name as budget_name,\
                                sum(price_subtotal2)\
                            from \
                                purchase_order_line pol\
                            left join\
                                product_product pp on product_id = pp.id\
                            left join\
                                account_budget_post abp on kdvn_budget_id = abp.id\
                            where order_id=%s\
                            group by\
                                pol.project_id,\
                                kdvn_budget_id,\
                                budget_name,\
                                order_id" % (o['id']))
                for project_id,budget_id,budgetname,amount in cr.fetchall():
                #self.pool.get('purchase.order.line').read(cr,uid,o['order_line'],['product_id','project_id','product_uom','price_subtotal2','name']):
                    #pr_id = budget_id
                    #prj_id = o.project_id.id
                    #raise osv.except_osv("E","%s-%s-%s" %(adv,retention,progress))
                    payment_details.append(self.payment_detail_create(project_id,budget_id,budgetname,amount,po_term['type'],adv,retention,progress))            
                if o['notes']:
                    new_description = po_term['name'] + "\n"+  o['notes']
                else:
                    new_description = po_term['name']
#                if po_term['due_date']:
#                    due_date=po_term['due_date']
                if po_term['due_date']:
                    payment = {
                        'paymentno':'',
                        'amount':this_progress_amount,
                        'tax_amount':this_tax_amount,
                        'advanced_amount':this_adv_amount,
                        'retention_amount':this_retention_amount,
                        'tax_per':int(o['tax_per']) or 0,
                        'supplier_id': o['partner_id'][0],
                        'currency_id': o['currency_id'][0],
                        'detail_ids': payment_details,
                        'order_id':o['id'], # For KDVN,
                        'project_id':o['project_id'][0],
                        'due_date':po_term['due_date'],
                        'description':new_description#po_term['name'] + "\n"+  o['notes']                        
                        }
                else:
                    payment = {
                        'paymentno':'',
                        'amount':this_progress_amount,
                        'tax_amount':this_tax_amount,
                        'advanced_amount':this_adv_amount,
                        'retention_amount':this_retention_amount,
                        'tax_per':int(o['tax_per']) or 0,
                        'supplier_id': o['partner_id'][0],
                        'currency_id': o['currency_id'][0],
                        'detail_ids': payment_details,
                        'order_id':o['id'], # For KDVN,
                        'project_id':o['project_id'][0],                        
                        'description':new_description#po_term['name'] + "\n"+  o['notes']                        
                        }
                #raise osv.except_osv("E",payment)
                kdvn_rop_id = self.pool.get('kdvn.request.of.payment').create(cr, uid, payment)
        return kdvn_rop_id

    def action_invoice_createBAK(self, cr, uid, ids, *args):
        res = False
        #for o in self.browse(cr, uid, ids):
        for o in self.read(cr, uid, ids,['order_payment_term_ids',
                                         'amount_total2',
                                         'order_line',
                                         'tax_per',
                                         'partner_id',
                                         'currency_id',
                                         'project_id',
                                         'id'
                                         ]): 
            raise osv.except_osv("E",o)       
            if o.rop_ids:
                raise osv.except_osv('Warning','Request of payment already exist')
            payment_details = []
            adv_amount = 0.0
            retention_amount = 0.0
            adv = 0.0
            retention = 0.0
            progress = 0.0
            for po_term in o.order_payment_term_ids:
                if po_term.type=='adv':
                    adv_amount = po_term.value_amount*o.amount_total2/100
                    adv = po_term.value_amount
                elif po_term.type=='re':
                    retention_amount = po_term.value_amount*o.amount_total2/100
                    retention = po_term.value_amount
                    
            for po_term in o.order_payment_term_ids:
                if po_term.type<>'p':
                    this_tax_amount = 0.0
                    this_progress_amount = 0.0
                    if po_term.type=='adv':
                        this_retention_amount = 0.0
                        this_adv_amount = adv_amount
                    else:
                        this_adv_amount = 0.0
                        this_retention_amount = retention_amount
                else:
                    progress = po_term.value_amount
                    this_tax_amount = o.tax_amount*po_term.value_amount/100.0
                    this_progress_amount = o.amount_total2*po_term.value_amount/100.0
                    this_adv_amount = - adv_amount*progress/100.0
                    this_retention_amount = - retention_amount*progress/100.0
                for ol in o.order_line:
                    if ol.product_id:
                        pr_id = ol.product_id.id
                    prj_id = o.project_id.id
                    payment_details.append(self.payment_detail_create(pr_id,ol,prj_id,po_term.type,adv,retention,progress))            
                payment = {
                    'amount':this_progress_amount,
                    'tax_amount':this_tax_amount,
                    'advanced_amount':this_adv_amount,
                    'retetion_amount':this_retention_amount,
                    'tax_per':int(o.tax_per) or 0,
                    'supplier_id': o.partner_id.id,
                    'currency_id': o.currency_id.id,
                    'detail_ids': payment_details,
                    'order_id':o.id, # For KDVN,
                    'project_id':o.project_id.id,
                    }
                #raise osv.except_osv("E",payment)
                kdvn_rop_id = self.pool.get('kdvn.request.of.payment').create(cr, uid, payment)
        return kdvn_rop_id
    
    def copy(self, cr, uid, id, default=None,context={}):
        if not default:
            default = {}
        typeoforder = False
        if context:
            if 'typeoforder' in context:
                typeoforder = context['typeoforder']
        res_user_obj=self.pool.get('res.users').read(cr,uid,uid,['name'],context)
        user_name=''
        if res_user_obj:
            user_name=str(res_user_obj['name'])
        if user_name<>'':
            user_name = " - " + user_name
        default.update({
            'rop_ids':False,
            'stock_picking_ids':False,
            'user_id':uid,
            #'order_payment_term_ids':False,
            'state':'draft',
            'exp_status':'draft',
#            'shipped':False,
#            'invoiced':False,
#            'invoice_id':False,
#            'picking_ids':[],
            'typeoforder':typeoforder,
            'name':'Not Avaiable'+user_name,
        })
        
        new_id= super(purchase_order, self).copy(cr, uid, id, default, context)
        self.pool.get('ir.rule').domain_get.clear_cache(cr.dbname)
        return new_id
purchase_order()

class purchase_order_line(osv.osv):
    _name = 'purchase.order.line'
    _inherit = 'purchase.order.line'
    
    def name_get(self, cr, uid, ids, context={}):
        if not len(ids):
            return []
        res = []
        for record in self.read(cr, uid, ids, ['sequence','name'], context):
            name = str(record['sequence']) + ". " +  record['name']
            res.append((record['id'],name ))
        return res
    
    def isINT(self,number):
        try:
            check = int(number)
            check = True
        except:
            check = False
        return check
    
    def isFLOAT(self,number):
        if type(number).__name__=='str':
            number=number.replace(",","")
        try:            
            check = float(number)
            check = True
        except:
            check = False
        return check
    
    def search(self, cr, user, args, offset=0, limit=None, order=None,  context=None, count=False):
        if context:
            if 'order_id' in context.keys():
                order_id=context['order_id']
                cr.execute("Select \
                                    id \
                            from\
                                purchase_order_line where order_id=%s" % order_id) 
                res = cr.fetchall()
                res1=[]
                for tmp in res:
                    res1.append(tmp[0])
                var_filter=res1
                args.append(('id','in',var_filter))
        return super(purchase_order_line,self).search(cr, user, args, offset, limit, order,context, count)
    
    def name_search(self, cr, user, name='', args=None, operator='ilike', context=None, limit=80):
        if context:
            if 'order_id' in context.keys():
                order_id=context['order_id']
                cr.execute("Select \
                                    id \
                            from\
                                purchase_order_line where order_id=%s" % order_id) 
                res = cr.fetchall()
                res1=[]
                for tmp in res:
                    res1.append(tmp[0])
                var_filter=res1
                args = args + [('id','in',var_filter)]
        if name:
            ids=[]
            if self.isINT(name):
                ids = self.search(cr, user, [('sequence','=',name)]+ args, limit=limit, context=context)
            if not len(ids):
                ids = self.search(cr, user, [('product_id','ilike',name)]+ args, limit=limit, context=context)
            if not len(ids) and self.isFLOAT(name):
                new_name = float(name.replace(',',""))
                ids = self.search(cr, user, [('price_unit','=',new_name)]+ args, limit=limit, context=context)
            if not len(ids):                
                ids = self.search(cr, user, [('name','ilike',name)]+ args, limit=limit, context=context)
        else:
            ids = self.search(cr, user, args, limit=limit, context=context)
        result = self.name_get(cr, user, ids, context)
        return result
    
    def _get_pol_budget_info(self, cr, uid, ids, name, arg,context):
        res = {}
        if ids:
            #pol_ids = ",".join(map(str,ids))
            for id in ids:
                res[id]= 0.0#{'budget_id':False,'budgetamount':False}
            cr.execute("Select \
                            pol.id,\
                            kdvn_budget_id as budget_id\
                        from \
                            purchase_order_line pol\
                        left join \
                            purchase_order po on pol.order_id=po.id\
                        left join\
                            product_product pp on pol.product_id=pp.id\
                   where pol.id in (%s) " % ",".join(map(str,ids)))            
            for pol_id,budget_id in cr.dictfetchall():
                res[pol_id]=budget_id
        return res
    
    def _get_pol_budget_amount_info(self, cr, uid, ids, name, arg,context):
        res = {}
        if ids:
            for id in ids:
                res[id]=0.0
            cr.execute("Select \
                            pol.id,\
                            coalesce(budget_amount,0) as budgetamount\
                        from \
                            purchase_order_line pol\
                        left join \
                            purchase_order po on pol.order_id=po.id\
                        left join\
                            product_product pp on pol.product_id=pp.id\
                        left join\
                            kdvn_budget_data kbd on pol.project_id=kbd.project_id and kdvn_budget_id = budget_id\
                   where pol.id in (%s) " % ",".join(map(str,ids)))            
            for pol_id,amount in cr.fetchall():
                res[pol_id]=amount
        return res
    
    def _get_pol_total_in_vnd(self, cr, uid, ids, name, arg,context):
        res = {}
        if ids:
            for id in ids:
                res[id]=0.0
            cr.execute("Select \
                            pol.id,\
                            fnpo_compute(fnpo_currnametoid('VND'),currency_id,date_order)*price_subtotal2*rate as amountvnd\
                        from \
                            purchase_order_line pol\
                        left join \
                            purchase_order po on pol.order_id=po.id\
                        left join \
                            vwpo_rate vwr on po.id=vwr.id\
                   where pol.id in (%s) " % ",".join(map(str,ids)))
            for pol_id,amount in cr.fetchall():
                res[pol_id]=amount
        return res
    
    def _price_unit_change(self,cr,uid,ids,qty,p_unit,discountp,p_subtotal2,plan_qty=False,special_case=False):
        change=False
        res={}
        new_qty=0
        if plan_qty and not special_case:
            new_qty = plan_qty
            qty = plan_qty
        elif plan_qty and special_case:
            new_qty = plan_qty
            qty = 0
        if not discountp:
            discountp=0.0
        if qty==0 and plan_qty:
            new_qty = plan_qty
            vdistcount=plan_qty*p_unit - plan_qty*p_unit*discountp/100
        else:
            new_qty = qty
            vdistcount=qty*p_unit - qty*p_unit*discountp/100
        if vdistcount!=p_subtotal2:
            change=True            
        if change:            
            #cr.execute("Update purchase_order set line_update=True where id=%d;" % (order_id))            
            #cr.execute("Update purchase_order set discount=(Select sum(price_unit*product_qty)-sum(price_subtotal2) as discount from purchase_order_line where order_id=%d),discount_percent=(Select (sum(price_unit*product_qty)-sum(price_subtotal2))/sum(price_unit*product_qty)*100.0 as discount_percent from purchase_order_line where order_id=%d) where id=%d;" % (order_id,order_id,order_id))
            res={'value':{'price_subtotal2':vdistcount,'product_qty':qty,'price_subtotal':new_qty*p_unit}}
        return res
    
    def _subtotal_2_change(self,cr,uid,ids,qty,p_unit,discountp,p_subtotal2,plan_qty):
        change=False
        res={}
        discountp= discountp or 0.0
        p_subtotal2=p_subtotal2 or 0.0
        if qty==0 and plan_qty<>0:
            qty=plan_qty
        #raise osv.except_osv(_('No Partner!'), _("Update purchase_order set discount=(Select sum(price_unit*product_qty)-sum(price_subtotal2) as discount from purchase_order_line where order_id=%d),discount_percent=(Select (sum(price_unit*product_qty)-sum(price_subtotal2))/sum(price_unit*product_qty)*100.0 as discount_percent from purchase_order_line where order_id=%d) where id=%d;" % (order_id,order_id,order_id)))
        if not (qty or p_unit) or (qty==0 or p_unit==0):
            vdistcount_p=0.0
        else:
            vdistcount_p=((qty*p_unit-p_subtotal2)*100.0/(qty*p_unit))
        if vdistcount_p!=discountp:
            change=True            
        if change:
            res={'value':{'discount_percent':vdistcount_p}}
        return res
    
    def _get_remain_budget(self, cr, uid, ids, name, arg,context):
        res ={}
        if ids:
            for id in ids:
                res[id]=0
            pol_ids = ",".join(map(str,ids))
            cr.execute("Select \
                            pol.id,\
                            coalesce(budget_amount,0)-\
                            coalesce(sum(coalesce(pol_cal.price_subtotal2,0)*coalesce(rate,1)*fnpo_compute(fnpo_currnametoid('VND'),po_cal.currency_id,po_cal.date_order)),0) as budget_remain_thistime\
                        from\
                            purchase_order_line pol\
                        left join\
                            kdvn_project kp on pol.project_id = kp.id\
                        left join\
                            purchase_order po on pol.order_id = po.id\
                        left join\
                            product_product pp on product_id = pp.id\
                        left join\
                            kdvn_budget_data kbd on pol.project_id = kbd.project_id and kdvn_budget_id = kbd.budget_id\
                        left join\
                            (Select \
                                price_subtotal2,\
                                order_id,\
                                kdvn_budget_id,\
                                project_id\
                            from\
                                purchase_order_line pol\
                            left join\
                                product_product pp on pol.product_id = pp.id) pol_cal on pp.kdvn_budget_id = pol_cal.kdvn_budget_id and pol.project_id = pol_cal.project_id\
                        left join\
                            purchase_order po_cal on pol_cal.order_id = po_cal.id and po.name>po_cal.name and po_cal.state not in ('draft','cancel') and po_cal.name like kp.code || '%'\
                        left join\
                            vwpo_rate vwr on po_cal.id=vwr.id\
                        where\
                            pol.id in (" + pol_ids + " )group by\
                            pol.id,budget_amount" )
            for id,remain in cr.fetchall():
                res[id]= remain
        return res
    
    def _get_remain_budget_backup(self, cr, uid, ids, name, arg,context):
        res ={}
        if ids:
            for pol in self.browse(cr,uid,ids):
                prd_id = pol.product_id.id or 0
                if pol.product_id.kdvn_budget_id:
                    budget_id = pol.product_id.kdvn_budget_id.id
                else:
                    budget_id = 0
                prj_id = pol.order_id.project_id.id or 0
                date_order = pol.order_id.date_order
                order_no = pol.order_id.name
                cr.execute("Select \
                                    budget_amount-\
                                    coalesce(sum(price_subtotal2*rate*fnpo_compute(fnpo_currnametoid('VND'),currency_id,date_order)),0) as remain\
                            from \
                                purchase_order po\
                            left join \
                                kdvn_project kp on po.project_id = kp.id\
                            left join \
                                purchase_order_line pol on po.id=order_id\
                            left join \
                                product_product pp on pol.product_id=pp.id\
                            left join \
                                vwpo_rate vwr on po.id=vwr.id\
                            left join\
                                kdvn_budget_data kbd on pol.project_id=kbd.project_id and kdvn_budget_id = budget_id\
                            where\
                                pol.project_id = "+str(prj_id)+ "\
                                and kdvn_budget_id=(select kdvn_budget_id from product_product where id="+ str(prd_id) +" limit 1)\
                                and PO.date_order<='" + str(date_order) +"'\
                                and po.name<'" + str(order_no) +"'\
                                and PO.state not in ('draft','cancel')\
                                and po.name like kp.code || '%'\
                            group by pol.project_id,budget_id,budget_amount;")        
                res_remain=cr.fetchone()
                if res_remain:            
                    budget_remain=res_remain[0]
                else:
                    cr.execute("Select\
                            budget_amount as actual_budget_amount\
                        from \
                            kdvn_budget_data kbd\
                        where \
                                project_id=%s and budget_id=%s" %(prj_id,budget_id))
                    res_remain=cr.fetchone()
                    if res_remain: 
                        budget_remain = res_remain[0]
                    else:
                        budget_remain = 0.0
                res[pol.id] = budget_remain 
        return res

    def product_id_change(self, cr, uid, ids, curr_id, product, qty, uom,partner_id,discount_p,project_id, description,price, date_order=False,order_no=False):
        if qty>1 or price>1 or type(description)==type('d'):
            change=False
        else:
            change = True
        if change:
            if not partner_id:
                raise osv.except_osv(_('No Supplier !'), _('You have to select a supplier in the purchase form !\nPlease set one supplier before choosing a product.'))
            if not product:
                return {'value': {'price_unit': 0.0,'budget_remain':0.0, 'name':'', 'product_uom' : False,'brand_name':False}, 'domain':{'product_uom':[]}}
            prod= self.pool.get('product.product').browse(cr, uid,product)
            lang=False
            if partner_id:
                lang=self.pool.get('res.partner').read(cr, uid, partner_id)['lang']
            #context['lang']=lang
            #context['partner_id'] = partner_id
            #raise osv.except_osv(_("Testing"),_("Date:%s-product:%s") % (str(date_order),str(product)))
            prod = self.pool.get('product.product').browse(cr, uid, product)
            prod_uom_po = prod.uom_id.id
            p_budget_id = prod.kdvn_budget_id.id
            brand_name = False
            brn = False
            for brn in prod.brand_ids:
                if not brand_name:
                    brand_name = brn.brandname_id.id
                if brn.default_brand:
                    brand_name = brn.brandname_id.id
            if not uom:
                uom = prod_uom_po
            if not date_order:
                date_order = time.strftime('%Y-%m-%d %H:%M:%S')
            price=0.0
            price_lst=self.pool.get('product.product').read(cr,uid,[product],['list_price'])[0]
            if price_lst:
                price=price_lst['list_price']
    
            qty = qty or 1.0
            seller_delay = 0
            for s in prod.seller_ids:
                seller_delay = s.delay
                if s.name.id == partner_id:
                    seller_delay = s.delay
                    temp_qty = s.qty # supplier _qty assigned to temp
                    if qty < temp_qty: # If the supplier quantity is greater than entered from user, set minimal.
                        qty = temp_qty
    
            dt = (DateTime.now() + DateTime.RelativeDateTime(days=seller_delay or 0.0)).strftime('%Y-%m-%d %H:%M:%S')
            prod_name = prod.name # Default is [Code] Name prod.partner_ref 
            discount_p=discount_p or 0.0
            p_subtotal2=qty*price-qty*price*discount_p/100
            #raise osv.except_osv("E",context)
    #        cr.execute("Select \
    #                            budget_amount-coalesce(sum(price_subtotal2*rate*fnpo_compute(fnpo_currnametoid('VND'),currency_id,date_order)),0) as remain\
    #                    from \
    #                        purchase_order po\
    #                    left join \
    #                        purchase_order_line pol on po.id=order_id\
    #                    left join \
    #                        product_product pp on pol.product_id=pp.id\
    #                    left join \
    #                        vwpo_rate vwr on po.id=vwr.id\
    #                    left join\
    #                        kdvn_project kp on po.project_id=kp.id\
    #                    left join\
    #                            kdvn_budget_data kbd on po.project_id=kbd.project_id and kdvn_budget_id = budget_id\
    #                    where\
    #                        po.project_id = "+str(project_id)+ "\
    #                        and kdvn_budget_id=(select kdvn_budget_id from product_product where id="+ str(product) +" limit 1)\
    #                        and PO.date_order<='" + str(date_order) +"'\
    #                        and po.name<'" + str(order_no) +"'\
    #                        and PO.state<>'cancel'\
    #                        and po.name like kp.code || '%'\
    #                    group by budget_amount;")
            
            #budget_remain=0.0
            res_remain=cr.fetchone()
            #if res_remain:
            #    budget_remain=res_remain[0]
            #else:
    #            cr.execute("Select\
    #                            budget_amount as actual_budget_amount\
    #                        from \
    #                            kdvn_budget_data kbd\
    #                            where \
    #                                project_id=%s and budget_id=%s" %(project_id,p_budget_id))
                #budget_id=cr.fetchone()[0]
                #main_budget_id=self.pool.get("budget.main.job").search(cr,uid,[('project_id','=',project_id),('budget_id','=',budget_id)])
                #pl_amount=self.pool.get("budget.main.job").read(cr,uid,main_budget_id[0],['planned_amount'])
                #budget_remain=cr.fetchone()[0]
            res = {'value': {   'price_unit': price, 'name':prod_name,
                                'date_planned': dt,'notes':prod.description_purchase,
                                'product_qty': qty,
                                'product_uom': uom,
                                'price_subtotal2':p_subtotal2,
                                #'budget_remain_thistime':budget_remain,
                                'brand_name':brand_name}}
        else:
            res = {'value':{}}
        return res
    
    def _get_paid_vnd(self, cr, uid, ids, name, arg,context):
        res={}
        if ids:
            pol_ids = ",".join(map(str,ids))
        #for pol in self.browse(cr,uid,ids):
            cr.execute("Select\
                            sum(coalesce(vr.rate,0)*fnpo_compute(krop.currency_id,fnpo_currnametoid('VND'),po.date_order)*kropd.amount) as payment_vnd\
                        from \
                            kdvn_request_of_payment krop\
                        left join\
                            kdvn_request_of_payment_detail kropd\
                        on\
                            krop.id=kropd.rop_id\
                        left join\
                            purchase_order po\
                        on \
                            order_id=po.id\
                        left join\
                            vwpo_rate vr\
                        on\
                            order_id=vr.id\
                        left join\
                            kdvn_payment kp\
                        on krop.id=payment_id\
                        where \
                            krop.state<>'draft'\
                            and krop.state<>'cancel'\
                            and kp.id is not null\
                            and product_id=%s\
                                and order_id=%s\
                        group by order_id,product_id" % (pol.product_id.id,pol.order_id.id))
            val=cr.fetchone()
            if val:
                val=val[0] or 0.0
            else:
                val=0.0
            res[pol.id]=val
        return res
    #Return Remaining budget   
                        
    def _cal_subtotal(self, cr, uid, ids, name, arg,context):
        res = {}
        if ids:
            pol_ids = ",".join(map(str,ids))
            cr.execute("Select \
                            pol.id,\
                            price_unit*(case when state<>'done' and po.special_case=True then plan_qty else product_qty end) as price_subtotal\
                        from \
                            purchase_order_line pol\
                        left join\
                            purchase_order po on pol.order_id = po.id\
                        where pol.id in (%s)" % pol_ids)
        for pol_id,subtotal in cr.fetchall():
            res[pol_id] =  subtotal
        return res
    #Purchase 
    
    def new_project_id(self, cr, uid, context={}):
        project_id = False
        if context:
            if 'order_id' in context:
                order_id = context['order_id']
                project_id = self.pool.get('purchase.order').read(cr,uid,[order_id],['project_id'])[0]
                if project_id:
                    project_id = project_id['project_id'][0]
        return project_id
    
    def new_product_id(self, cr, uid, context={}):
        prj_id = False
        if context:
            if 'order_id' in context:
                order_id = context['order_id']
                cr.execute("Select product_id from purchase_order_line pol where order_id=%s order by sequence desc limit 1" % order_id)
                #project_id = self.pool.get('purchase.order.line').read(cr,uid,[order_id],['project_id'])[0]
                new_product_obj = cr.fetchone()
                prj_id =False
                if new_product_obj:
                    prj_id = new_product_obj[0]
        return prj_id
    
    def _new_seq(self, cr, uid, context={}):
        new_seq=1
        if context:
            if 'order_id' in context:
                cr.execute("Select coalesce(max(sequence),0) from purchase_order_line where order_id=%s" % context['order_id'])
#                po_line_ids=self.search(cr,uid,[('order_id','=',context['order_id'])])
#                payments=self.read(cr,uid,po_line_ids,['sequence'],context)
                #new_seq=0
                sq = cr.fetchone()
                if sq:
                    new_seq=sq[0]
                    new_seq=new_seq+1  
        return new_seq
    
    _columns={
              
            'move_ids': fields.one2many('stock.move', 'purchase_line_id', 'Reservation', readonly=True, ondelete='set null'),
            'move_dest_id': fields.many2one('stock.move', 'Reservation Destination', ondelete='set null'),
            
            'product_id': fields.many2one('product.product', 'Product', domain=[('purchase_ok','=',True)]),#change_default=True
            'project_id':fields.many2one('kdvn.project','Project'),
            'brand_name':fields.many2one('kdvn.brand.name','Brand'),
            'budget_id':fields.function(_get_pol_budget_info,string="Budget",type="many2one",relation="account.budget.post",method=True),              
            'product_qty': fields.float('Qty.', required=True,digits=(16, int(config['price_accuracy']))),#, digits=(16,2)
            'plan_qty':fields.float('Plan Qty.',digits=(16, int(config['price_accuracy']))),#, digits=(16,2)
            #'price_unit': fields.float('Unit Price', required=True, digits=(16, int(config['price_accuracy']))),            
            'name': fields.char('Description', size=120, required=True),
            'product_uom': fields.many2one('product.uom', 'Product UOM', required=True),
            'product_id': fields.many2one('product.product', 'Product', domain=[('purchase_ok','=',True)]),
            'price_unit': fields.float('Price', required=True,digits=(16, int(config['price_accuracy']))),
            'price_subtotal': fields.function(_cal_subtotal,type='float', method=True, string='Subtotal'),

            'order_id': fields.many2one('purchase.order', 'Order Ref', required=True, ondelete='cascade'),
            'amountvnd':fields.function(_get_pol_total_in_vnd,string='VND',method=True,type='float',digits=(20,4)),#,store={'purchase.order.line':(lambda self, cr, uid, ids, c={}: ids, None, 5)}),
            'budgetamount':fields.function(_get_pol_budget_amount_info,string="Budget Amount",method=True,type="float"),
            'discount_percent':fields.float("Disc.(%)"),
            'price_subtotal2':fields.float("After Discount"),
            
            'budget_remain_thistime':fields.function(_get_remain_budget,string="Remain VND",type='float',method=True),

            #'paid_vnd':fields.function(_get_paid_vnd,string="Paid VND",method=True,type="float"),
            'sequence': fields.integer('Sequence', help="The sequence field is used to order details"),         
        }
    _sql_constraints = [
        ('budget_does_not_avaiable', 'CHECK (fn_check_constraint_project_budget(order_id,project_id,product_id))',  'KDVN Error: The budget code of the project does not exists !')] 
    _order = "order_id,sequence"
    _defaults = {
        'discount_percent': lambda *a: 0.0,
        'project_id':new_project_id,
        'product_id':new_product_id,
        'sequence':_new_seq,
        #'partner_address_id': lambda self, cr, uid, context: context.get('partner_id', False) and self.pool.get('res.partner').address_get(cr, uid, [context['partner_id']], ['default'])['default'],
        }
#    
    def init2(self,cr):
        cr.execute('''CREATE OR REPLACE FUNCTION fn_check_constraint_project_budget(p_order_id integer,p_project_id integer,p_product_id integer)  RETURNS boolean AS\
                                    $BODY$\
                                    declare\
                                    prj_id2 integer;\
                                    chk_c boolean;\
                                begin\
                                if $2 IS NULL then\
                                Select into prj_id2 project_id from purchase_order where id=$1;\
                                else\
                                prj_id2 = $2;\
                                end if;\
                                if exists(Select kbd.id from kdvn_budget_data kbd left join product_product pp on kbd.budget_id = pp.kdvn_budget_id where project_id=prj_id2 and pp.id=$3) then\
                                chk_c = true;\
                                else\
                                chk_c = false;\
                                end if;\
                                return chk_c;                                end;                                $BODY$ LANGUAGE plpgsql VOLATILE COST 100''');
                        
                        #        raise osv.except_osv("e",'''CREATE OR REPLACE FUNCTION fn_check_constraint_project_budget(p_order_id integer,p_project_id integer,p_product_id integer)\
#                                    RETURNS boolean AS\
#                                    $BODY$\
#                                    declare\
#                                    prj_id2 integer;\
#                                    chk_c boolean;\
#                                begin\
#                                if $2 IS NULL then\
#                                Select into prj_id2 project_id from purchase_order where id=$1;\
#                                else\
#                                prj_id2 = $2;\
#                                end if;\
#                                if exists(Select kbd.id from kdvn_budget_data kbd left join product_product pp on kbd.budget_id = pp.kdvn_budget_id where project_id=prj_id2 and pp.id=$3) then\
#                                chk_c = true;\
#                                else\
#                                chk_c = false;\
#                                end if;\
#                                return chk_c;                                end;                                $BODY$ LANGUAGE plpgsql VOLATILE COST 100''');
                
    def init1(self,cr):    
        #Update Purchase OLine
        cr.execute("Select tgname from pg_trigger where tgname='trgupdatepo_lineupdate'");
        res=cr.fetchall()
        if res:
            cr.execute("drop TRIGGER trgupdatepo_lineupdate on purchase_order_line")
            
        cr.execute("CREATE OR REPLACE FUNCTION trgfnupdatepo_lineupdate()\
                          RETURNS trigger AS\
                            $BODY$declare\
                                id1 integer;\
                            begin\
                                if new.discount_percent<>old.discount_percent or new.price_subtotal2<>old.price_subtotal2 then\
                                    update purchase_order set line_update=True where id=new.order_id;\
                                end if;\
                                return NULL;\
                            end;$BODY$\
                          LANGUAGE 'plpgsql' VOLATILE\
                          COST 100;")
        cr.execute("CREATE TRIGGER trgupdatepo_lineupdate\
                      AFTER UPDATE\
                      ON purchase_order_line\
                      FOR EACH ROW\
                      EXECUTE PROCEDURE trgfnupdatepo_lineupdate();")
        
        #Insert Purchase OLine
        cr.execute("Select tgname from pg_trigger where tgname='trginsertpo_lineupdate'");
        res=cr.fetchall()
        if res:
            cr.execute("drop TRIGGER trginsertpo_lineupdate on purchase_order_line")
        cr.execute("CREATE OR REPLACE FUNCTION trgfninsertpo_lineupdate()\
                          RETURNS trigger AS \
                            $BODY$declare\
                                id1 integer;\
                            begin\
                            if new.discount_percent>0 then\
                update purchase_order set line_update=True where id=new.order_id;\
                                end if;\
                                return NULL;\
                            end;$BODY$ \
                          LANGUAGE 'plpgsql' VOLATILE\
                          COST 100;")
        cr.execute("CREATE TRIGGER trginsertpo_lineupdate\
                      AFTER insert\
                          ON purchase_order_line\
                          FOR EACH ROW\
                          EXECUTE PROCEDURE trgfninsertpo_lineupdate();")
        
        #Delete Purchase OLine
        cr.execute("Select tgname from pg_trigger where tgname='trgdeletepo_lineupdate'");
        res=cr.fetchall()
        if res:
            cr.execute("drop TRIGGER trgdeletepo_lineupdate on purchase_order_line")
        cr.execute("CREATE OR REPLACE FUNCTION trgfndeletepo_lineupdate()\
                          RETURNS trigger AS \
                            $BODY$\
                            begin\
                                update purchase_order set line_update=True where id=old.order_id;\
                                return NULL;\
                            end;$BODY$ \
                          LANGUAGE 'plpgsql' VOLATILE\
                          COST 100;")
        cr.execute("CREATE TRIGGER trgdeletepo_lineupdate\
                      AFTER DELETE\
                          ON purchase_order_line\
                          FOR EACH ROW\
                          EXECUTE PROCEDURE trgfndeletepo_lineupdate();")
purchase_order_line()
#End of Purchase
